package cn.itcast.account.service.impl;

import cn.itcast.account.entity.AccountFreeze;
import cn.itcast.account.mapper.AccountFreezeMapper;
import cn.itcast.account.mapper.AccountMapper;
import cn.itcast.account.service.TCCAccountService;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Description TCCAccountServiceImpl
 * @Author junjie Wu 吴俊杰
 * @Date 2024-03-25
 */
@Slf4j
@Service
public class TCCAccountServiceImpl implements TCCAccountService {

    @Autowired
    private AccountFreezeMapper accountFreezeMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Override
    public void deduct(String userId, int money) throws InterruptedException {
        //模拟try阻塞
        Thread.sleep(20000);
        //业务悬挂
        AccountFreeze freeze = accountFreezeMapper.selectById(RootContext.getXID());
        if(freeze != null) {

            return;
        }
        //try的过程
        //1.扣减金额
        accountMapper.deduct(userId,money);
        //2.插入一条冻结记录到冻结表中
        AccountFreeze accountFreeze = new AccountFreeze();
        accountFreeze.setXid(RootContext.getXID());
        accountFreeze.setFreezeMoney(money);
        accountFreeze.setState(AccountFreeze.State.TRY);
        accountFreeze.setUserId(userId);
        accountFreezeMapper.insert(accountFreeze);
        log.info("userid = {},冻结金额 money = {}, 成功 ",userId,money);
    }

    @Override
    public boolean confirm(BusinessActionContext ctx) {
        //删除那条冻结记录
       return accountFreezeMapper.deleteById(ctx.getXid()) == 1;
    }

    @Override
    public boolean cancel(BusinessActionContext ctx) {
        //先查询下冻结记录表
        String xid = ctx.getXid();
        AccountFreeze accountFreeze = accountFreezeMapper.selectById(xid);
        String userId = ctx.getActionContext("userId").toString();
        if(accountFreeze == null) {
            log.error("没有这条事务记录 事务id = {}",xid);
            accountFreeze = new AccountFreeze();
            accountFreeze.setXid(xid);
            accountFreeze.setUserId(userId);
            accountFreeze.setState(AccountFreeze.State.CANCEL);
            accountFreeze.setFreezeMoney(0);
            accountFreezeMapper.insert(accountFreeze);
            return true;
        }
        if(accountFreeze.getState().intValue() == AccountFreeze.State.CANCEL) {
            return true;
        }

        log.debug("开始回滚金额: {},userId={}", xid, userId);
        accountMapper.refund(userId,
               accountFreeze.getFreezeMoney());
        accountFreeze.setUserId(userId);
        accountFreeze.setXid(xid);
        accountFreeze.setState(AccountFreeze.State.CANCEL);
        accountFreeze.setFreezeMoney(0);
        accountFreezeMapper.updateById(accountFreeze);

        return accountFreezeMapper.updateById(accountFreeze) == 1;
    }
}
